#include <memory.h>

#include "GInputDeviceKeyboard.h"

namespace GEngine
{
	/********************************************************/
	/*					GKeyboardState						*/
	/********************************************************/

	GKeyboardState::GKeyboardState()
	{
		Reset();
	}

	GKeyboardState::~GKeyboardState()
	{
	}

	void GKeyboardState::Reset()
	{
		memset(SemanticStates, 0, sizeof(bool) * G_KS_COUNT);
	}

	const GKeyboardState& GKeyboardState::operator = (const GKeyboardState& Other)
	{		
		memcpy(SemanticStates, Other.SemanticStates, sizeof(bool) * G_KS_COUNT);

		return *this;
	}

	/********************************************************/
	/*				GInputDeviceKeyboard					*/
	/********************************************************/

	GInputDeviceKeyboard::GInputDeviceKeyboard(GModule* Owner, void* DeviceHandle) 
		: GInputDevice(Owner, DeviceHandle)
	{
	}

	GInputDeviceKeyboard::~GInputDeviceKeyboard()
	{
	}

	void GInputDeviceKeyboard::AdvanceState()
	{
		PreviousState = CurrentState;
	}

	bool GInputDeviceKeyboard::CheckInput(const GInput* Input) const OVERRIDE
	{
		GInputState State = Input->GetState();
		GKeyboardSemantics Semantic = Input->GetSemantic().Keyboard;

		bool Current = CurrentState.SemanticStates[Semantic];
		bool Previous = PreviousState.SemanticStates[Semantic];

		// Compare against previous state
		bool Result = false;
		switch (State)
		{
		case G_IS_PRESSED:
			Result = !Previous && Current;
			break;
		case G_IS_PRESSING:
			Result = Previous && Current;
			break;
		case G_IS_RELEASED:
			Result = Previous && !Current;
			break;
		}

		return Result;
	}

	GUInt32 GInputDeviceKeyboard::GetType() const OVERRIDE
	{
		return G_DT_KEYBOARD;
	}

	const char* GInputDeviceKeyboard::GetName() const OVERRIDE
	{
		return "Keyboard";
	}

	void GInputDeviceKeyboard::Reset()
	{
		CurrentState.Reset();
		PreviousState.Reset();
	}

	bool GInputDeviceKeyboard::Update()
	{
		if (!GInputDevice::Update())
		{
			return false;
		}

		AdvanceState();

		return true;
	}

	const char*	GInputDeviceKeyboard::GetSemanticName(GKeyboardSemantics Semantic)
	{
		return GKeyboardSemanticNames[Semantic];
	}
}